| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | 1× 1× | // // // // // // // // // import circleRipple from './circleRipple' import * as domUtil from '../utils/domUtil' export default { props: { centerRipple: { type: Boolean, default: true }, rippleWrapperClass: { }, color: { type: String, default: '' }, opacity: { type: Number } }, data () { return { nextKey: 0, ripples: [] } }, mounted () { this.ignoreNextMouseDown = false }, methods: { start (event, isRippleTouchGenerated) { if (this.ignoreNextMouseDown && !isRippleTouchGenerated) { this.ignoreNextMouseDown = false return } this.ripples.push({ key: this.nextKey++, color: this.color, opacity: this.opacity, style: this.centerRipple ? {} : this.getRippleStyle(event) }) this.ignoreNextMouseDown = isRippleTouchGenerated }, end () { if (this.ripples.length === 0) return this.ripples.splice(0, 1) this.stopListeningForScrollAbort() }, stopListeningForScrollAbort () { if (!this.handleMove) this.handleMove = this.handleTouchMove.bind(this) document.body.removeEventListener('touchmove', this.handleMove, false) }, startListeningForScrollAbort (event) { this.firstTouchY = event.touches[0].clientY this.firstTouchX = event.touches[0].clientX document.body.addEventListener('touchmove', this.handleMove, false) }, handleMouseDown (event) { if (event.button === 0) { this.start(event, false) } }, handleTouchStart (event) { if (event.touches) { this.startListeningForScrollAbort(event) this.startTime = Date.now() } this.start(event.touches[0], true) }, handleTouchMove (event) { const deltaY = Math.abs(event.touches[0].clientY - this.firstTouchY) const deltaX = Math.abs(event.touches[0].clientX - this.firstTouchX) // 判断滚动 6px if (deltaY > 6 || deltaX > 6) this.end() // const timeSinceStart = Math.abs(Date.now() - this.startTime) // if (timeSinceStart > 300) { // this.stopListeningForScrollAbort() // return // } }, getRippleStyle (event) { const el = this.$refs.holder const elHeight = el.offsetHeight const elWidth = el.offsetWidth const offset = domUtil.getOffset(el) const isTouchEvent = event.touches && event.touches.length const pageX = isTouchEvent ? event.touches[0].pageX : event.pageX const pageY = isTouchEvent ? event.touches[0].pageY : event.pageY const pointerX = pageX - offset.left const pointerY = pageY - offset.top const topLeftDiag = this.calcDiag(pointerX, pointerY) const topRightDiag = this.calcDiag(elWidth - pointerX, pointerY) const botRightDiag = this.calcDiag(elWidth - pointerX, elHeight - pointerY) const botLeftDiag = this.calcDiag(pointerX, elHeight - pointerY) const rippleRadius = Math.max( topLeftDiag, topRightDiag, botRightDiag, botLeftDiag ) const rippleSize = rippleRadius * 2 const left = pointerX - rippleRadius const top = pointerY - rippleRadius return { directionInvariant: true, height: rippleSize + 'px', width: rippleSize + 'px', top: top + 'px', left: left + 'px' } }, calcDiag (a, b) { return Math.sqrt((a * a) + (b * b)) } }, components: { 'circle-ripple': circleRipple } } |